/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package evidence.model.modeloveTridy;

import evidence.model.pomocneTridy.Time;
import evidence.model.pomocneTridy.TimeException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.util.HSSFRegionUtil;
import org.apache.poi.ss.util.CellRangeAddress;

/**
 *
 * @author Protheo
 */
public class DenEvidence implements Serializable{
    public static final long serialVersionUID = 1;
    private List<DenniZaznam> polozky;
    private Map<String, Double> hodiny;
    private Map<String, Integer> doprava;
    private Double celkHodiny;
    private Integer celkDoprava;
    private Boolean prestavka = false;

    public DenEvidence(Time zacatek, Time konec, String typ, String klient, String ukon, int doprava, Boolean prestavka, String nepritomnost) {
        this();
        this.polozky.add(new DenniZaznam(zacatek, konec, typ, klient, ukon, doprava, prestavka, nepritomnost));
        this.setTruePrestavka(prestavka);
        this.update();
    }

    public DenEvidence(){
        this.polozky = new ArrayList<DenniZaznam>();
        this.hodiny = new HashMap<String, Double>(TypSluzby.pocetSluzeb());
        this.doprava = new HashMap<String, Integer>(TypSluzby.pocetSluzeb());
        this.celkHodiny = new Double(0);
        this.celkDoprava = 0;
    }

    public void addZaznam(Time zacatek, Time konec, String typ, String klient, String ukon, int doprava, Boolean prestavka, String nepritomnost){
        this.polozky.add(new DenniZaznam(zacatek, konec, typ, klient, ukon, doprava, prestavka, nepritomnost));
        this.setTruePrestavka(prestavka);
        this.update();
    }

    public void removeZaznam(int pozice){
        boolean pom = this.polozky.get(pozice).isPrestavka();
        if (pom){
            this.prestavka = false;
        }
        this.polozky.remove(pozice);
        this.update();
    }

    public void insertZaznam(int pozice, Time zacatek, Time konec, String typ, String klient, String ukon, int doprava, Boolean prestavka, String nepritomnost){
        this.polozky.add(pozice, new DenniZaznam(zacatek, konec, typ, klient, ukon, doprava, prestavka, nepritomnost));
        this.setTruePrestavka(prestavka);
        this.update();
    }

    public void editZaznam(int pozice, Map<Integer, Object> prop){
        boolean pom = this.polozky.get(pozice).isPrestavka();
        if (pom && !((Boolean)prop.get(DenniZaznam.PROP_PRE))){
            this.prestavka = false;
        }
        this.polozky.get(pozice).setProp(prop);
        this.update();
    }

    private void update(){
        this.celkDoprava = 0;
        this.celkHodiny = 0.0;
        this.doprava.clear();
        this.hodiny.clear();
        for (Iterator<DenniZaznam> it = polozky.iterator(); it.hasNext();) {
            DenniZaznam dz = it.next();
            if (this.hodiny.containsKey(dz.getTyp())){
                double pom = this.hodiny.get(dz.getTyp());
                pom += dz.getDelka();
                this.hodiny.put(dz.getTyp(), pom);
            } else {
                this.hodiny.put(dz.getTyp(), dz.getDelka());
            }
            if (this.doprava.containsKey(dz.getTyp())){
                int pom = this.doprava.get(dz.getTyp());
                pom += dz.getDoparava();
                this.doprava.put(dz.getTyp(), pom);
            } else {
                this.doprava.put(dz.getTyp(), dz.getDoparava());
            }
            this.celkHodiny += dz.getDelka();
            this.celkDoprava += dz.getDoparava();
        }
    }

    public Double getCelkHodiny() {
        return celkHodiny;
    }

    public Map<String, Double> getHodiny() {
        return Collections.unmodifiableMap(hodiny);
    }

    public Integer getCelkDoprava() {
        return celkDoprava;
    }

    public Map<String, Integer> getDoprava() {
        return Collections.unmodifiableMap(doprava);
    }

    public List<List<Object>> getPolozky() {
        List<List<Object>> ret = new ArrayList<List<Object>>();
        for (int i = 0; i < this.polozky.size(); i++) {
            DenniZaznam dz = this.polozky.get(i);
            ret.add(dz.getData());
        }
        return ret;
    }

    public Boolean isPrestavka(){
        return this.prestavka;
    }

    private void setTruePrestavka(Boolean prestavka){
        if (prestavka){
            this.prestavka = prestavka;
        }
    }

    public Time getPosledni(){
        Time konec = null;
        try{
            konec = this.polozky.get(this.polozky.size()-1).getKonec();
            if (this.polozky.get(this.polozky.size()-1).isPrestavka()){
            konec = konec.prictiCas(0, 30);
        }
        }catch(ArrayIndexOutOfBoundsException ex){
            try {
                konec = new Time(8, 0);
            } catch (TimeException ex1) {
                Logger.getLogger(DenEvidence.class.getName()).log(Level.SEVERE, null, ex1);
            }
        }
        return konec;
    }

    public int export(HSSFSheet sheet, int row){
        if (this.polozky.isEmpty()){
            this.setBorder(row, sheet);
            return row+1;
        }
        int radek = row;
        boolean zapsanyHod = false;
        for (int i = 0; i < polozky.size(); i++) {
            DenniZaznam dz = polozky.get(i);
            dz.export(sheet.getRow(radek));
            if(!zapsanyHod 
                    && sheet.getRow(radek).getCell(9).getStringCellValue().equals("")
                    && !dz.getKlient().toLowerCase().equals("dovolená")){
                sheet.getRow(radek).getCell(9).setCellValue(this.celkHodiny);
                zapsanyHod = true;
            }
            if(radek == 52 || radek == 105){
                radek += 2;
            } else {
                radek++;
            }
        }
        this.setBorder(radek-1, sheet);
        return radek;
    }

    private void setBorder(int radek, HSSFSheet sheet){
        CellRangeAddress range = new CellRangeAddress(radek, radek, 0, 9);
        HSSFRegionUtil.setBorderBottom(2, range, sheet, sheet.getWorkbook());
    }
}
